template <typename T>
class MessageQueue {
public:
    explicit MessageQueue(int capacity) : capacity_(capacity) {}

    void Push(const T& msg) {
        std::unique_lock<std::mutex> lock(mutex_);
        condvar_.wait(lock, [this]() { return queue_.size() < capacity_;});
        queue_.push(msg);
        condvar_.notify_all();
    }

    T Pop() {
        std::unique_lock<std::mutex> lock(mutex_);
        condvar_.wait(lock, [this]() { return !queue_.empty();});
        T msg = queue_.front();
        queue_.pop();
        condvar_.notify_all();
        return msg;
    }
    bool empty(){
        std::unique_lock<std::mutex> lock(mutex_);
        return queue_.empty();
    }

private:
    std::queue<T> queue_;
    std::mutex mutex_;
    std::condition_variable condvar_;
    int capacity_;
};
